package swb.api.com.api;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import swb.api.com.repository.dto.WithdrawAccount;
import swb.api.com.repository.dto.WithdrawRecord;
import swb.api.com.service.WithdrawService;
import swb.api.com.vo.req.WithdrawRequest;
import swb.api.com.vo.resp.WithdrawResponse;
import swb.api.com.vo.Result;

import java.util.List;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 提现相关的控制器类，提供提现申请、查询记录、获取账户信息等接口。
 */
@Slf4j
@RestController
@RequestMapping("/api/withdraw")
@Api(tags = "提现管理接口")
public class WithdrawController {

    @Autowired
    private WithdrawService withdrawService;
    @Value("${md5Key:swb123!@#}")
    private String md5Key;

    /**
     * 发起提现申请
     *
     * @param userId  用户ID，从请求头中获取
     * @param request 提现请求参数，包含账户ID和金额
     * @param sign 签名，用于验证请求的合法性 userId=用户ID&accountId=账户ID&amount=金额
     * @return 返回提现响应结果
     */
    @PostMapping("/apply")
    @ApiOperation(value = "发起提现申请", notes = "用户发起提现申请，系统将处理提现请求并生成提现记录")
    public Result<WithdrawResponse> applyWithdraw(
            @ApiParam(value = "用户ID", required = true) @RequestHeader("User-Id") Long userId,
            @ApiParam(value = "提现请求参数", required = true) @RequestBody WithdrawRequest request,
            @ApiParam(value = "签名", required = true) @RequestParam("sign") String sign) {
        // 验证签名
        if (!validateSignature(userId, request, sign)) {
            return Result.error("签名验证失败");
        }

        WithdrawResponse response = withdrawService.applyWithdraw(userId, request.getAccountId(), request.getAmount());
        return Result.success(response, "提现申请提交成功");
    }

    /**
     * 验证签名
     * @param userId 用户ID
     * @param request 提现请求参数
     * @param sign 签名
     * @return 验证结果
     */
    private boolean validateSignature(Long userId, WithdrawRequest request, String sign) {
        // 构造签名字符串
        StringBuilder sb = new StringBuilder();
        sb.append("userId=").append(userId)
                .append("&accountId=").append(request.getAccountId())
                .append("&amount=").append(request.getAmount());

        // 使用密钥进行签名（这里使用简单的MD5示例）
        String expectedSign = generateSign(sb.toString(), md5Key);
        log.info("Expected Sign: {}, Actual Sign: {}", expectedSign, sign);
        return expectedSign.equals(sign);
    }

    /**
     * 生成签名
     * @param data 待签名数据
     * @param secret 密钥
     * @return 签名结果
     */
    private String generateSign(String data, String secret) {
        // 这里使用简单的MD5算法，实际应用中建议使用更安全的算法
        String signData = data + secret;
        return DigestUtils.md5Hex(signData);
    }

    /**
     * 查询用户的提现记录列表
     *
     * @param userId 用户ID，从请求头中获取
     * @param status 提现状态筛选条件（可选）
     * @param page   分页页码，默认为0
     * @param size   每页大小，默认为10
     * @return 返回提现记录列表
     */
    @GetMapping("/records")
    @ApiOperation(value = "查询提现记录列表", notes = "根据用户ID和可选状态查询提现记录列表，支持分页")
    public Result<Page<WithdrawRecord>> getWithdrawRecords(
            @ApiParam(value = "用户ID", required = true) @RequestHeader("User-Id") Long userId,
            @ApiParam(value = "提现状态(0:待处理, 1:处理中, 2:成功, 3:失败)", required = false) @RequestParam(required = false) Integer status,
            @ApiParam(value = "页码", defaultValue = "0") @RequestParam(defaultValue = "0") int page,
            @ApiParam(value = "每页大小", defaultValue = "10") @RequestParam(defaultValue = "10") int size) {
        Page<WithdrawRecord> records = withdrawService.getWithdrawRecords(userId, status, page, size);
        return Result.success(records, "查询成功");
    }

    /**
     * 根据记录ID获取提现记录详情，并验证用户权限
     *
     * @param userId    用户ID，从请求头中获取
     * @param recordId  提现记录ID，从路径变量中获取
     * @return 若记录存在且属于当前用户则返回记录详情，否则返回404
     */
    @GetMapping("/records/{recordId}")
    @ApiOperation(value = "获取提现记录详情", notes = "根据记录ID获取提现记录详情，并验证用户权限")
    public Result<WithdrawRecord> getWithdrawRecordDetail(
            @ApiParam(value = "用户ID", required = true) @RequestHeader("User-Id") Long userId,
            @ApiParam(value = "提现记录ID", required = true) @PathVariable Long recordId) {
        WithdrawRecord record = withdrawService.getWithdrawRecordDetail(recordId);
        // 验证记录是否存在以及是否属于当前用户
        if (record == null || !record.getUserId().equals(userId)) {
            return Result.error("记录不存在或无权限访问");
        }
        return Result.success(record, "查询成功");
    }

    /**
     * 获取用户默认的提现账户信息
     *
     * @param userId 用户ID，从请求头中获取
     * @return 若存在默认账户则返回账户信息，否则返回404
     */
    @GetMapping("/default-account")
    @ApiOperation(value = "获取默认提现账户", notes = "获取用户设置的默认提现账户信息")
    public Result<WithdrawAccount> getDefaultAccount(
            @ApiParam(value = "用户ID", required = true) @RequestHeader("User-Id") Long userId) {
        WithdrawAccount account = withdrawService.getDefaultAccount(userId);
        if (account == null) {
            return Result.error("默认账户不存在");
        }
        return Result.success(account, "查询成功");
    }
}
